package org.sundatagroup.aurora.core.entity.pojo;

import java.util.ArrayList;
import java.util.List;

import org.sundatagroup.aurora.core.entity.IJsonEntity;
import org.sundatagroup.aurora.core.entity.model.ProjectModel;
import org.sundatagroup.aurora.core.entity.particle.Particle;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

/**
 * <p>工程的 POJO 类. 一个工程关联多个 {@link Module}
 * </p>
 * 
 * @version 0.1.1
 * <li>补充 texts 和 desc 字段
 * </li>
 * 
 * @version 0.2.0
 * <li>补充 particles 成员
 * </li>
 * 
 * @author CharlesChen
 * @author Zdream
 * @date 2018-06-08
 * @since 0.1
 */
public class Project implements IJsonEntity {
	/*
	 * 注解为主键标识
	 */
	private int pid;
	private String name;
	private List<Module> modules;
	private JsonObject options;
	
	/**
	 * <p>粒子配置表项
	 * <p>particle[index] 为第 index 个模块的配置项列表
	 * </p>
	 * @since 0.2.0
	 */
	private ArrayList<List<Particle>> particles = new ArrayList<>();
	
	/**
	 * 文本数据, 专门传给文字层的数据.
	 * @since v0.1.1
	 */
	private JsonArray texts;
    
    /**
     * 描述. 这个数据不会传到前端
     */
	private String desc;
	
	public Project() {
		// do nothing
	}
	
	public Project(String name) {
		this(name, null);
	}

	public Project(String name, List<Module> modules) {
		this.pid = 0;
		this.name = name;
		this.modules = modules;
	}

	/**
	 * 检查参数是否正常
	 * @throws IllegalArgumentException
	 * @return bool
	 */
	public boolean isValid() {
		if (pid > 0 && name.length() != 0) {
		    return true;
		} else {
			throw new IllegalArgumentException("Project参数配置有误，请检查！");
		}
	}

	/**
	 * 转换List<Module>为JsonArray
	 * @return
	 */
	public JsonArray modulesArray() {
		JsonArray array = new JsonArray(modules.size());
		modules.forEach((m) -> {array.add(m.toJson());});
		return array;
	}

    @Override
	public JsonObject toJson() {
    	JsonObject jo = new JsonObject();
    	jo.addProperty("pid", pid);
    	jo.addProperty("name", name);
    	jo.add("modules", modulesArray());
    	jo.add("options", options);
    	jo.add("texts", texts);
    	return jo;
    }

	/**
	 * 转换{@link Project}为{@link ProjectModel}
	 * @return
	 */
	public ProjectModel toModel() {
		ProjectModel pm = new ProjectModel();
		pm.setName(name);
		pm.setPid(pid);
		
		ArrayList<Integer> mids = new ArrayList<>(modules.size());
		modules.forEach((m) -> {mids.add(m.getMid());});
		
		pm.setModules(mids);
		pm.setOptions(options);
		pm.setTexts(texts);
		pm.setDesc(desc);
		return pm;
	}
	
	/**
	 * 转换{@link ProjectModel}为{@link Project}
	 * 注：省略module 项填充，在对应Service层完成填充。
	 * @param pm
	 * @return
	 */
	public static Project fromModel(ProjectModel pm) {
		Project p = new Project(pm.getName());
		p.setPid(pm.getPid());
		p.setOptions(pm.getOptionToJson());
		p.setTexts(pm.getTextToJson());
		p.setDesc(pm.getDesc());
		return p;
	}

	public int getPid() {
		return pid;
	}

	public void setPid(int pid) {
		this.pid = pid;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Module> getModules() {
		return modules;
	}

	public void setModules(List<Module> modules) {
		this.modules = modules;
	}

	public JsonObject getOptions() {
		return options;
	}

	public void setOptions(JsonObject options) {
		this.options = options;
	}

	public JsonArray getTexts() {
		return texts;
	}

	public void setTexts(JsonArray texts) {
		this.texts = texts;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	/**
	 * @return
	 * @since 0.2.0
	 */
	public ArrayList<List<Particle>> getParticles() {
		return particles;
	}

	@Override
	public String toString() {
		return "Project [pid=" + pid + ", name=" + name + ", modules=" + modules + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + pid;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Project other = (Project) obj;
		if (pid != other.pid)
			return false;
		return true;
	}
}
